home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
3_14.lha
/
3_14
/
3_14.c
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
7KB
|
340 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
include <stream.h>
include <string.h>
include <stdlib.h>
ifndef RAND_MAX
define RAND_MAX 32767
endif
include <ctype.h>
nt no_of_errors;
ouble error(char *s)
cerr << "error: " << s << "\n";
no_of_errors++;
return 1;
include "3_14b.c" // d_f_va, maxargs, variable, interp_func, struct name
onst TBLSZ = 23;
ame *table[TBLSZ];
nt lookhash(char *p)
int ii = 0;
while (*p) ii = ii << 1 ^ *p++;
if (ii < 0) ii = -ii;
return ii % TBLSZ;
ame *look(char *p, int ins=0)
int ii = lookhash(p);
for (name *n = table[ii]; n; n=n->next)
if (strcmp(p, n->string) == 0)
return n;
if (ins == 0) error("name not found");
name *nn = new name;
nn->string = new char[strlen(p)+1];
strcpy(nn->string, p);
nn->next = table[ii];
n->nargs = variable; // #include "3_13c.c" /* EXPAND4 */
nn->value = 1;
table[ii] = nn;
return nn;
nline name *insert(char *s) { return look(s, 1); }
include "3_14a.c" // enum token_value { NAME, ... };
include "3_14d1.c" // double *curfuncargs = 0;
oken_value curr_tok;
ouble number_value;
onst int namesize = 100;
har name_string[namesize];
oken_value get_token();
ouble expr(), term(), prim();
ouble expr()
/cerr << "expr()\n"; /* DELETE */
double left = term();
for (;;)
{
switch (curr_tok)
{
case PLUS: get_token();
left += term();
break;
case MINUS: get_token();
left -= term();
break;
default:
return left;
}
}
ouble term()
/cerr << "term()\n"; /* DELETE */
double left = prim();
for (;;)
{
switch (curr_tok)
{
case MUL: get_token();
left *= prim();
break;
case DIV:
get_token();
double d = prim();
if (d == 0) return error("divide by 0");
left /= d;
break;
default:
return left;
}
}
include "3_14c2.c" // char *get_funcdefn()
include "3_14e.c" // double interpfunc(double*, char*)
ouble prim()
/cerr << "prim(): curr_tok = " << chr(curr_tok) << "\n"; /* DELETE */
switch (curr_tok)
{
case NUMBER:
/cerr << "prim(): case NUMBER:\n"; /* DELETE */
get_token();
return number_value;
include "3_14d2.c" // case DOL:
case NAME:
/cerr << "prim(): case NAME:\n"; /* DELETE */
get_token();
/cerr << "prim(): curr_tok = " << chr(curr_tok) << "\n"; /* DELETE */
if (curr_tok == ASSIGN) // same as before
{
/cerr << "prim: case NAME: ASSIGN\n"; /* DELETE */
name *n = insert(name_string);
get_token();
n->value = expr();
return n->value;
}
include "3_14d.c" // else if (curr_tok == LP)
include "3_14c.c" // else if (curr_tok == LB)
else // same as before
{
/cerr << "prim: case NAME: LOOKUP\n"; /* DELETE */
name *n = look(name_string);
if (n->nargs == variable)
return n->value;
else
return error("( expected");
}
case MINUS:
/cerr << "prim(): case MINUS:\n"; /* DELETE */
get_token();
return -prim();
case LP:
/cerr << "prim(): case LP:\n"; /* DELETE */
get_token();
double e = expr();
if (curr_tok != RP)
return error(") expected");
get_token();
return e;
case END:
/cerr << "prim(): case END:\n"; /* DELETE */
return 1;
default:
/cerr << "prim(): default:\n"; /* DELETE */
return error("primary expected");
}
oken_value get_token()
char ch;
do {
if (!cin.get(ch)) return curr_tok = END;
} while (ch != '\n' && isspace(ch));
switch (ch)
{
case ';': case '\n':
cin >> WS;
return curr_tok = PRINT;
include "3_14a2.c"
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
cin.putback(ch);
cin >> number_value;
return curr_tok = NUMBER;
default:
if (isalpha(ch))
{
char *p = name_string;
*p++ = ch;
while (cin.get(ch) && isalnum(ch) && p < &name_string[namesize-1])
*p++ = ch;
if (p == &name_string[namesize])
while (cin.get(ch) && isalnum(ch))
;
cin.putback(ch);
*p = 0;
return curr_tok = NAME;
}
error("bad token");
return curr_tok = PRINT;
}
* declare helper functions for */
* sqrt(), log(), sin() and random() */
include <math.h>
/ return the square root of e0
tatic double dosqrt(double e[])
return (e[0] < 0) ?
error("sqrt: requires non-negative number") :
sqrt(e[0]);
/ return the natural log of e0
tatic double dolog(double e[])
return (e[0] <= 0) ?
error("log: requires positive number") :
log(e[0]);
/ return the sin of e0
tatic double dosin(double e[])
return sin(e[0]);
/ return a random number between [e0, e1)
tatic double dorandom(double e[])
return rand() / ( (double) RAND_MAX+1) *
(e[1] - e[0]) + e[0];
tatic double doexp(double e[]) { return exp(e[0]); }
tatic double docos(double e[]) { return cos(e[0]); }
tatic double dotan(double e[]) { return tan(e[0]); }
tatic double doatan(double e[]) { return atan(e[0]); }
tatic double dolog10(double e[])
if (e[0] <= 0) return error("log10: requires non-positive number");
else return log10(e[0]);
tatic double doexp10(double e[])
return pow(10, e[0]);
tatic double doasin(double e[])
if (e[0] > 1 || e[0] < -1) return error("asin: requires |x| <= 1.0");
else return asin(e[0]);
tatic double doacos(double e[])
if (e[0] > 1 || e[0] < -1) return error("acos: requires |x| <= 1.0");
else return acos(e[0]);
tatic double dopow(double e[])
double x = e[0];
double y = e[1];
if (x == 0 && y <= 0) return error("pow: x == 0 requires y > 0");
else if (x < 0 && y != (double)(int)y)
return error("pow: x < 0 requires int y");
else return pow(x, y);
oid insertfunction(char *funcname,
int nargs, d_f_va funcptr)
name *n = insert(funcname);
n->nargs = nargs;
n->funcptr = funcptr;
nt main(int argc, char **argv)
switch (argc)
{
case 1: break;
case 2: cin = *new istream(strlen(argv[1]), argv[1]); break;
default: error("too many arguments"); return 1;
}
// initialize known variables
insert("pi")->value = 3.1415926535897932385;
insert("e")->value = 2.7182818284590452354;
// initialize known functions
insertfunction("sqrt", 1, (d_f_va)dosqrt);
insertfunction("log", 1, (d_f_va)dolog);
insertfunction("sin", 1, (d_f_va)dosin);
insertfunction("random", 2, (d_f_va)dorandom);
insertfunction("exp", 1, (d_f_va)doexp);
insertfunction("log10", 1, (d_f_va)dolog10);
insertfunction("pow", 2, (d_f_va)dopow);
insertfunction("cos", 1, (d_f_va)docos);
insertfunction("tan", 1, (d_f_va)dotan);
insertfunction("asin", 1, (d_f_va)doasin);
insertfunction("acos", 1, (d_f_va)doacos);
insertfunction("atan", 1, (d_f_va)doatan);
while (cin)
{
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr() << "\n";
}
return no_of_errors;